/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.googlecode.datawander.codegenerator;

import com.googlecode.datawander.i18n.I18n;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import org.apache.log4j.Logger;

/**
 *
 * @author Marcin Stachniuk
 */
public class OracleConnectorGenerator {

    private static final Logger logger = Logger.getLogger(DatabasesConnectorsGenerator.class);

    /**
     * New line char. Use to generate new line in file.
     */
    public static final String NEW_LINE;

    /**
     * String with one ident in files with source code
     */
    private static final String INDENT = "    ";

    private List<String> metaClassList;

    // static inicialize block
    static {
        NEW_LINE = System.getProperty("line.separator");
    }

    private String packageName = null;


    public void generateOracleConnector(String filePath) throws CodeGenerationException {
        logger.trace("generateOracleConnector(" + filePath + ")");

        String fileAbsolutePath = null;
        if(packageName != null && packageName.length() != 0) {
            fileAbsolutePath = filePath + File.separator +
                    packageName.replace(".", File.separator)
                    + File.separatorChar + "OracleConnector.java";
        } else {
             fileAbsolutePath = filePath + File.separatorChar + "OracleConnector.java";
        }
        String message = I18n.getString("oracleconnectorpath");
        message = String.format(message, fileAbsolutePath);
        logger.debug(message);

        File file = new File(fileAbsolutePath);

        try {
            file.createNewFile();
        } catch (IOException ex) {
            logger.error(ex, ex);
            throw new CodeGenerationException(ex.getMessage());
        }

        try {
            PrintWriter out = new PrintWriter(fileAbsolutePath);

            // generation head od file
            out.append(SourceCodeGenerator2Object.SOURCE_FILE_HEADER);

            generatePackage(out);

            generateImports(out);

            generateClass(out);

            generateFielsd(out);

            generateInitDatabaseDriverMethod(out);

            generateGetConnectionMethod(out);

            generateSetters(out);

            out.append("}" + NEW_LINE);

            out.close();
        } catch(FileNotFoundException ex) {
            logger.error(ex, ex);
            throw new CodeGenerationException(
                    I18n.getString("codegenerationexceptionproblem"));
        }
    }

    public String getPackageName() {
        return packageName;
    }

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    private void generatePackage(PrintWriter out) {
        if(packageName != null) {
            out.append("package " + packageName + ";" + NEW_LINE + NEW_LINE);
        }
    }

    private void generateImports(PrintWriter out) {
        out.append("import java.sql.Connection;" + NEW_LINE);
        out.append("import java.sql.DriverManager;" + NEW_LINE);
        out.append("import java.sql.SQLException;" + NEW_LINE + NEW_LINE);
    }

    private void generateClass(PrintWriter out) {
        out.append("public class OracleConnector {" + NEW_LINE);
    }

    private void generateFielsd(PrintWriter out) {
        out.append(INDENT + "private static String driver = \"" +
                "oracle.jdbc.driver.OracleDriver\";" + NEW_LINE);
        out.append(INDENT + "private static String url = null;" + NEW_LINE);
        out.append(INDENT + "private static String username = null;" + NEW_LINE);
        out.append(INDENT + "private static String password = null;" +
                NEW_LINE + NEW_LINE);
    }

    private void generateInitDatabaseDriverMethod(PrintWriter out) {
        out.append(INDENT + "public static void initDatabaseDriver() throws " +
                "Exception {" + NEW_LINE);
        out.append(INDENT + INDENT + "try {" + NEW_LINE);
        out.append(INDENT + INDENT + INDENT + "Class.forName(driver);  " +
                "// load Oracle driver" + NEW_LINE);
        out.append(INDENT + INDENT + INDENT + "System.out.println(" +
                "\"Oracle driver loaded\");" + NEW_LINE);
        out.append(INDENT + INDENT + "} catch(ClassNotFoundException e) {"
                + NEW_LINE);
        out.append(INDENT + INDENT + INDENT + "System.out.println(" +
                "\"No load Oracle driver\");" + NEW_LINE);
        out.append(INDENT + INDENT + INDENT + "throw new Exception(" +
                "\"No load Oracle driver\");" + NEW_LINE);
        out.append(INDENT + INDENT + "}" + NEW_LINE);
        out.append(INDENT + "}" + NEW_LINE + NEW_LINE);
    }

    private void generateGetConnectionMethod(PrintWriter out) {
        out.append(INDENT + "public static Connection getConnection() " +
                "throws Exception {" + NEW_LINE);
        out.append(INDENT + INDENT + "Connection conn = null;" + NEW_LINE);
        out.append(INDENT + INDENT + "try {" + NEW_LINE);
        out.append(INDENT + INDENT + INDENT +
                "conn = DriverManager.getConnection(url, username, password);" +
                NEW_LINE);
        out.append(INDENT + INDENT + INDENT +
                "System.out.println(\"Oracle database conected\");" +
                NEW_LINE);
        out.append(INDENT + INDENT + "} catch (SQLException ex) {" +
                NEW_LINE);
        out.append(INDENT + INDENT + INDENT + 
                "System.out.println(\"Oracle database no conected\");" + NEW_LINE);
        out.append(INDENT + INDENT + INDENT + 
                "throw new Exception(\"Oracle database no conected\");" + NEW_LINE);
        out.append(INDENT + INDENT + "}" + NEW_LINE);
        out.append(INDENT + INDENT + "return conn;" + NEW_LINE);
        out.append(INDENT + "}" + NEW_LINE + NEW_LINE);
    }

    private void generateSetters(PrintWriter out) {
        out.append(INDENT + "public static void setPassword(String password) {"
                + NEW_LINE);
        out.append(INDENT + INDENT + "OracleConnector.password = password;" +
                NEW_LINE);
        out.append(INDENT + "}" + NEW_LINE + NEW_LINE);

        out.append(INDENT + "public static void setUrl(String url) {"
                + NEW_LINE);
        out.append(INDENT + INDENT + "OracleConnector.url = url;" +
                NEW_LINE);
        out.append(INDENT + "}" + NEW_LINE + NEW_LINE);

        out.append(INDENT + "public static void setUsername(String username) {"
                + NEW_LINE);
        out.append(INDENT + INDENT + "OracleConnector.username = username;" +
                NEW_LINE);
        out.append(INDENT + "}" + NEW_LINE + NEW_LINE);
    }

    public String getClassName() {
        if(packageName != null) {
            return (packageName.endsWith(".") ? packageName : packageName + ".")
                    + "OracleConnector";
        } else {
            return "OracleConnector";
        }
    }
}
